import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:pp_net/pp_bean_factory.dart';
import 'package:pp_net/pp_net.dart';

class PPResponse<T> {
  static int emptyCode = 1011;

  /// 状态码
  int? code;

  /// 状态码说明
  String? message;

  /// 渲染数据
  T? data;
  List<T>? dataArray;
  PPException? exception;

  PPResponse({this.code, this.message, this.data, this.dataArray});

  factory PPResponse.fromJson(json) {
    // json 渲染json数据
    var code = -1;
    try {
      if (json["code"] != null) {
        try {
          code = json["code"];
        } catch (e) {
          code = -1;
        }
      } else {
        return PPResponse(code: code, message: "服务器数据格式不对", data: null);
      }

      if (code != PPNetConfig.instance.successCode) {
        var message = getErrorMessage(json);
        return PPResponse(code: code, message: message, data: null);
      }

      var data = json["data"];
      if (data == null) {
        return PPResponse(code: emptyCode, message: "没有相关数据", data: null);
      }
      if (data is List) {
        return PPResponse(
            code: code,
            message: getErrorMessage(json),
            dataArray: PPBeanFactory.generateModelArray<T>(data));
      }
      return PPResponse(
          code: code,
          message: getErrorMessage(json),
          data: PPBeanFactory.generateModel<T>(data));
    } catch (e) {
      return PPResponse(code: code, message: "未知错误", data: null);
    }
  }

  static String getErrorMessage(dynamic json) {
    var error = "";
    var message = json["message"];
    var msg = json["msg"];
    if (message != null) {
      error = "$message";
    } else if (msg != null) {
      error = "$msg";
    }
    return error;
  }
}

class PPResponseSet {
  Map<String, dynamic> responseData = <String, dynamic>{};
  Map<String, dynamic> exceptionData = <String, dynamic>{};
  Map<String, dynamic> jsonData = <String, dynamic>{};

  List<T>? getDataList<T>(String path) {
    var data = jsonData[path];
    if (data == null) {
      return null;
    }
    var code = data["code"];
    if (code == PPNetConfig.instance.successCode) {
      PPResponse result = PPResponse<T>.fromJson(data);
      responseData[path] = result;
      return result.dataArray as List<T>?;
    } else {
      var message = PPResponse.getErrorMessage(data);
      exceptionData[path] = PPException(code!, message);
      return null;
    }
  }

  T? getData<T>(String path) {
    var data = jsonData[path];
    if (data == null) {
      return null;
    }
    var code = data["code"];

    if (code == PPNetConfig.instance.successCode) {
      PPResponse result = PPResponse<T>.fromJson(data);
      responseData[path] = result;
      return result.data;
    } else {
      var message = PPResponse.getErrorMessage(data);
      exceptionData[path] = PPException(code!, message);
      return null;
    }
  }

  PPException? getException(String path) {
    var exception = exceptionData[path];
    if (exception == null) {
      return null;
    }
    return exception;
  }

  void addData(Response response) {
    var key = response.requestOptions.path;
    var data = jsonDecode(response.toString());
    jsonData[key] = data;
  }
}
